#include <rclcpp/rclcpp.hpp>
#include <rclcpp/parameter_client.hpp>

class ParameterReaderNode : public rclcpp::Node {
public:
    ParameterReaderNode() : Node("parameter_reader") {
        param_client_node_ = std::make_shared<rclcpp::Node>("param_client_node");
        // 创建参数客户端
        param_client_ = std::make_shared<rclcpp::SyncParametersClient>(
            param_client_node_, "add_on_set_node");
        // 使用定时器定期获取参数
        // timer_ = this->create_wall_timer(
        //     std::chrono::seconds(2),
        //     std::bind(&ParameterReaderNode::timer_callback, this));
        sync_callback();
    }

private:
    rclcpp::SyncParametersClient::SharedPtr param_client_;
    rclcpp::Node::SharedPtr param_client_node_;
    rclcpp::TimerBase::SharedPtr timer_;
    void timer_callback() {
        if (!param_client_->service_is_ready()) {
            RCLCPP_WARN(this->get_logger(), "Parameter service not ready");
            return;
        }
        try {
            // 获取参数列表
            auto param_names = param_client_->list_parameters({"name", "age","height","camera","motor"}, 0);
            for (const auto& name : param_names.names) {
                try {
                    // 输出name和value
                    if(name=="name"){
                        auto value = param_client_->get_parameter<std::string>(name);
                        RCLCPP_INFO(this->get_logger(), "Parameter %s: %s", name.c_str(), value.c_str());
                    }
                    else if(name=="age"){
                        auto value = param_client_->get_parameter<int>(name);
                        RCLCPP_INFO(this->get_logger(), "Parameter %s: %d", name.c_str(), value);
                    }
                    else if(name=="height"){
                        auto value = param_client_->get_parameter<double>(name);
                        RCLCPP_INFO(this->get_logger(), "Parameter %s: %f", name.c_str(), value);
                    }else if(name=="camera"){
                        auto value = param_client_->get_parameter<std::string>(name);
                        RCLCPP_INFO(this->get_logger(), "Parameter %s: %s", name.c_str(), value.c_str());
                    }else if(name=="camera.color"){
                        auto value = param_client_->get_parameter<std::string>(name);
                        RCLCPP_INFO(this->get_logger(), "Parameter %s: %s", name.c_str(), value.c_str());
                    }
                    else{
                        auto value = param_client_->get_parameter<int>(name);
                        RCLCPP_INFO(this->get_logger(), "Parameter %s: %d", name.c_str(), value);
                    }
                    /// @todo(wuguo): 通配输出所有级别的参数
                    
                    // else if(name=="motor"){
                    //     auto value = param_client_->get_parameter<std::string>(name);
                    //     RCLCPP_INFO(this->get_logger(), "Parameter %s: %s", name.c_str(), value.c_str());
                    // }
                } catch (const rclcpp::exceptions::ParameterUninitializedException& e) {
                    RCLCPP_WARN(this->get_logger(), "Parameter %s not set", name.c_str());
                }
            }
            RCLCPP_INFO(this->get_logger(), "\n");
        } catch (const std::exception& e) {
            RCLCPP_ERROR(this->get_logger(), "Failed to get parameters: %s", e.what());
        }
    }

    void sync_callback() {
        try {
            RCLCPP_INFO(this->get_logger(), "Waiting to parameters...");
            auto value = param_client_->get_parameter<std::string>("name");
            RCLCPP_INFO(this->get_logger(), "Parameter %s: %s", "name", value.c_str());
        } catch (const std::exception& e) {
            RCLCPP_ERROR(this->get_logger(), "Failed to get parameters: %s", e.what());
        }
    }
};

int main(int argc, char** argv) {
    rclcpp::init(argc, argv);
    auto node = std::make_shared<ParameterReaderNode>();
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}